
import { findData, addSlaveData } from "@/components/js/db";

import globalVariable from "@/components/js/Global";
// create an empty modbus client
var ModbusRTU = require("modbus-serial");

var client = new ModbusRTU();
var client_cfg = {};
var channels = [];


// list of meter's id
const metersIdList = [];

const getMetersValue = async meters => {
  try {
    // get value of all meters
    for (let meter of meters) {
      // output value to console
      // console.log();
      await getMeterValue(meter);
      // await getMeterValue(meter);
      // wait 100ms before get another device
      await sleep(parseInt(client_cfg.time_interval));

      globalVariable.SeConnStatus("Connected")
      // console.log(gconnstatus);
    }
  } catch (e) {
    // if error, handle them here (it should not)
    // gconnstatus = "ERROR";
    globalVariable.SeConnStatus("RUNERROR")
    console.log(e);
  } finally {
    // after get all data from salve repeate it again
    if (globalVariable.RunStatus == 0) {

      globalVariable.SeConnStatus("Stoped")
      client.close();
      return;
    } else {
      setImmediate(() => {
        getMetersValue(metersIdList);
      });
    }
  }
};

const getMeterValue = async id => {
  try {
    if (!client.isOpen) {
      client.connectTCP(client_cfg.slaveip, {
        port: client_cfg.slaveport
      });
    }

    await client.setID(id);
    // read the 1 registers starting at address 0 (first register)
    let cache = new Object();

    for (let items of channels) {
      let f = items.channel.func;
      let address = items.channel.address;
      let quantity = items.channel.quantity;

      if (f === "FC1") {
        let d = await client.readCoils(address, quantity);
        let n = 0;
        while (n < quantity) {
          let key = "FC1_" + (Array(4).join(0) + address + n).slice(-4);
          cache[key] = d.data[n] ? 1 : 0;
          n++;
        }
      } else if (f === "FC2") {
        let d = await client.readDiscreteInputs(address, quantity);
        let n = 0;
        while (n < quantity) {
          let key = "FC2_" + (Array(4).join(0) + address + n).slice(-4);
          cache[key] = d.data[n] ? 1 : 0;
          n++;
        }
      } else if (f === "FC3") {
        let d = await client.readHoldingRegisters(address, quantity);
        let n = 0;
        while (n < quantity) {
          let key = "FC3_" + (Array(4).join(0) + address + n).slice(-4);
          cache[key] = d.data[n];
          n++;
        }
      } else if (f === "FC4") {
        let d = await client.readInputRegisters(address, quantity);
        let n = 0;
        while (n < quantity) {
          let key = "FC4_" + (Array(4).join(0) + address + n).slice(-4);
          cache[key] = d.data[n];
          n++;
        }
      }
    }
    //  console.log("FUNC_Fx", cache);
    if (
      Object.prototype.isPrototypeOf(cache) &&
      Object.keys(cache).length === 0
    ) {
      console.log("null", cache);
    } else {
      addSlaveData(cache);
    }

    return cache;
  } catch (e) {
    // if error return -1
    return -1;
  }
};

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

// start get value

const getDevicecfg = () => {
  findData({
    type: "conf"
  }).then(res => {
    res.forEach((item, index, arr) => {
      //current clean array
      metersIdList.splice(0,metersIdList.length);
      metersIdList.push(parseInt(item.conf.deviceid));
      // console.log("metersIdList", metersIdList);

      client_cfg = JSON.parse(JSON.stringify(item.conf));
    });
  });
};

const getChannelcfg = () => {
  findData({
    type: "channel"
  }).then(res => {
    channels = JSON.parse(JSON.stringify(res));
  });
};





export function connect_to_slave() {
  globalVariable.SetRunStatus(1);
  getDevicecfg();
  getChannelcfg();
  getMetersValue(metersIdList);
  
}
export function disconnect_to_slave() {
  globalVariable.SetRunStatus(0);
}

